# 多周期
# 买入条件：日MACD金叉、周RSI小于50
# 卖出条件：价格较最高收盘价回撤5%卖出
from __future__ import (absolute_import, division, print_function, unicode_literals)
from sklearn.preprocessing import MinMaxScaler
from indicators.KDJ import KDJ
import backtrader as bt
import backtrader.feeds as btfeeds
import backtrader.indicators as btind
import datetime
import pandas as pd
import csv
from collections import defaultdict
from indicators.wave_index_ind import wave_index_ind
from indicators.ssa_index_ind import ssa_index_ind
import numpy as np
class aiStrategy5r (bt.Strategy):


    # 策略参数
    params = dict(
        period=20,  # 均线周期
        look_back_days=30,
        printlog=False,
        period_ema_fast=10,
        period_ema_slow=100,
        short_window=30,
        long_window=60,
        N1=3,
        N2=50,
        N3=25,
        wave_window=20,
        wave_two_window=50,
        wave_three_window=70,
        ssa_window=15
    )

    def __init__(self):
        # 存储不同数据的技术指标
        self.inds = dict()
        # 存储特定股票的订单，key为股票的代码
        self.orders = dict()
        # 遍历所有数据
        #for d in self.datas:
        for i, d in enumerate(self.datas):
            #i=len(self.datas)
            self.orders[d._name] = None
            # 为每个数据定义字典，存储技术指标
            self.inds[d] = dict()
            try:
                # 判断d是否为日线数据
                if 0 == i % 2:
                    #macd
                    self.inds[d]['crossup']= btind.CrossUp(btind.MACD(d).macd, btind.MACD(d).signal)
                    self.inds[d]['macd'] = btind.MACD(d).macd
                    self.inds[d]['signal'] = btind.MACD(d).signal
                    #波动率

                    #高低点
                    self.inds[d]['N_Low'] = bt.ind.Lowest(d.low, period=self.p.N2)
                    self.inds[d]['N_High'] = bt.ind.Highest(d.low, period=self.p.N1)

                    # 移动平均线
                    self.inds[d]['sma3'] = bt.indicators.SimpleMovingAverage(d, period=3)
                    self.inds[d]['sma5']= bt.indicators.SimpleMovingAverage(d, period=5)
                    self.inds[d]['sma10'] = bt.indicators.SimpleMovingAverage(d, period=10)
                    self.inds[d]['sma20'] = bt.indicators.SimpleMovingAverage(d, period=20)
                    self.inds[d]['sma30']= bt.indicators.SimpleMovingAverage(d, period=30)
                    self.inds[d]['sma60'] = bt.indicators.SimpleMovingAverage(d, period=60)
                    # kdj
                    self.inds[d]['K'] = KDJ( data=d).lines.K
                    self.inds[d]['D']= KDJ( data=d).lines.D
                    self.inds[d]['J'] = KDJ( data=d).lines.J
                    # 自定义指标
                    self.inds[d]['ssa'] = ssa_index_ind(ssa_window=self.params.ssa_window, data=d, subplot=False)
                    # RSI
                    #d.rsi = btind.RSI_Safe(d)
                    self.inds[d]['rsi'] = btind.RSI_Safe(d)
                    # boll
                    self.inds[d]['top'] = bt.indicators.BollingerBands(d, period=self.p.N1).top
                    self.inds[d]['bot'] = bt.indicators.BollingerBands(d, period=self.p.N1).bot

                    self.inds[d]['wave'] = wave_index_ind(wave_window=self.p.wave_window, data=d.close, subplot=False)
                    self.inds[d]['wave_two'] = wave_index_ind(wave_window=self.p.wave_two_window, data=d.close,subplot=False)
                    self.inds[d]['wave_three'] = wave_index_ind(wave_window=self.p.wave_three_window, data=d.close,subplot=False)

                # d为周线数据
                else:
                    #d.rsi= btind.RSI_Safe(d)
                    #print('111111')
                    #break;
                    self.inds[d]['rsi'] = btind.RSI_Safe(d)
                    #.btindRelativeStrengthIndex(d)
                    #.RelativeStrengthIndex()RSI_Safe(d)
            except Exception as err:
               break

    def next(self):
        #print(self.datetime.date())
        for i, d in enumerate(self.datas):
            # 如果处理周线数据则跳过买卖条件，因为已在日线数据判断处理过
              if 1 != i % 2:
                        #continue
            #处理逻辑为，如果昨天macd金叉
            #and self.inds[self.datas[i - 1]]['rsi'][0] <50 and self.inds[self.datas[i - 1]]['rsi'][0] >35
            #if self.inds[d]['crossup'][-1] :
                    close5  = d.close[-5]
                    close = d.close[0]
                    indexData = [] #指标数据
                    #indexData =np.array(indexData)
                    resData = [] #输出数据
                    data = []  # 输出数据
                    res = []
                    data = self.getData(self.inds[self.datas[i]], 'top', 7,5)
                    data =[x / close5 for x in data]
                    indexData = indexData + data
                    data = self.getData(self.inds[self.datas[i]], 'bot', 7,5)
                    data = [x / close5 for x in data]
                    indexData = indexData + data
                    indexData = indexData + self.getData(self.inds[self.datas[i]], 'rsi', 7,5)
                    indexData = indexData + self.getData(self.inds[self.datas[i - 1]], 'rsi', 7,5)
                    indexData = indexData + self.getData(self.inds[self.datas[i]], 'ssa', 7,5)
                    indexData = indexData + self.getData(self.inds[self.datas[i]], 'J', 7,5)
                    indexData = indexData + self.getData(self.inds[self.datas[i]], 'D', 6,5)
                    indexData = indexData + self.getData(self.inds[self.datas[i]], 'K', 6,5)
                    data = self.getData(self.inds[self.datas[i]], 'sma60', 6,5)
                    data = [x / close5 for x in data]
                    indexData = indexData + data
                    data = self.getData(self.inds[self.datas[i]], 'sma30', 6,5)
                    data = [x / close5 for x in data]
                    indexData = indexData + data
                    data = self.getData(self.inds[self.datas[i]], 'sma20', 6,5)
                    data = [x / close5 for x in data]
                    indexData = indexData + data
                    data = self.getData(self.inds[self.datas[i]], 'sma10', 6,5)
                    data = [x / close5 for x in data]
                    indexData = indexData + data
                    data =  self.getData(self.inds[self.datas[i]], 'sma5', 6,5)
                    data = [x / close5 for x in data]
                    indexData = indexData + data
                    data = self.getData(self.inds[self.datas[i]], 'sma3', 6,5)
                    data = [x / close5 for x in data]
                    indexData = indexData + data
                    data = self.getData(self.inds[self.datas[i]], 'N_High', 0,1)
                    data = [x / close5 for x in data]
                    indexData = indexData + data
                    data = self.getData(self.inds[self.datas[i]], 'N_Low', 0,1)
                    data = [x / close5 for x in data]
                    indexData = indexData + data
                    indexData = indexData + self.getData(self.inds[self.datas[i]], 'wave_three', 6,5)
                    indexData = indexData + self.getData(self.inds[self.datas[i]], 'wave_two', 6,5)
                    indexData = indexData + self.getData(self.inds[self.datas[i]], 'wave', 6,5)
                    indexData = indexData + self.getData(self.inds[self.datas[i]], 'signal', 6,5)
                    #indexData = indexData + self.getData(self.inds[self.datas[i]], 'crossup', 6)
                    indexData = indexData + self.getData(self.inds[self.datas[i]], 'macd', 6,5)
                    indexData = [x * 10 for x in indexData]
                    #print(indexData)
                    #print(d.N_Low[0],self.datas[i + 1].datetime.date(0))
                    #print(d.macd[-3],d.macd[-2],d.macd[-1],d.signal[-3],d.signal[-2],d.signal[-1]
                    #      ,d.sma3[-1],d.sma5[-1],d.sma10[-1],d.sma20[-1],d.sma30[-1],d.sma60[-1],d.K[-3],d.K[-2],d.K[-1]
                    #      ,d.D[-3],d.D[-2],d.D[-1],d.J[-3],d.J[-2],d.J[-1],d.rsi[-3],d.rsi[-2],d.rsi[-1]
                    #      ,d.bot[-3],d.bot[-2],d.bot[-1],d.top[-3],d.top[-2],d.top[-1]
                    #      ,d.N_Low[-1],d.N_High[-1],d.open[-3],d.close[-3],d.open[-2],d.close[-2],d.open[-1],d.close[-1])
                    #bili = ((close - close5)/close5 )*100*50
                    #if bili>0:
                    #  bili=10
                    #elif bili<-0:
                    #  bili=-10



                    #resData.append(bili)
                    bili = ((close - close5) / close5) * 100
                    resData.append(bili)
                    scaler = MinMaxScaler()
                    indexData = np.array(indexData)
                    #print(len(indexData))
                    lennum = len(indexData)
                    indexData = indexData.reshape(-1, 1)
                    # 使用训练集来训练换算器 scaler，并且调整数据使之更平滑
                    smoothing_window_size = 20
                    for di in range(0, lennum, smoothing_window_size):
                            scaler.fit(indexData[di:di + smoothing_window_size, :])
                            indexData[di:di + smoothing_window_size, :] = scaler.transform( indexData[di:di + smoothing_window_size, :])
                    indexData = indexData.reshape(-1)
                    #print( d.volume[0])

                    num = int(d.volume[0])


                    path = """E:\\ai\\cvs\\train\\supplier_data_5_%s.csv""" % (num)


                    with open(path, 'a',encoding='utf-8',newline="") as f:
                        writer = csv.writer(f)
                        st ='['+','.join(str(i) for i in indexData)+']'
                        res.append(st)
                        st ='['+','.join(str(i) for i in resData) +']'
                        res.append(st)
                        res.append(self.datas[i].datetime.date(-5))
                        #print(self.datas[i].dataname.date())
                        writer.writerow(res)
                        #writer.writerow(['8', 'zahng', '19', '87', '97', '77'])

                    #print(indexData)
                    #print(resData)

    def getData(self,data,name,end,st):
        indexData = []  # 指标数据
        for i in range(st,(end+st)):
            d = float(data[name][-i])
            if np.isnan(d):
              indexData.append(0)
            else:
              #absd = abs(d)
              #if absd <5:
              #    d=d*10
              indexData.append(d)
            #print(data[name] [-i])
            #print('   ')
        #indexData = np.array(indexData)
        return indexData


    #判断自定义指标是否连涨
    def getFronB(self, data,name,  end):
        for i in range(0, end):
            if data[name][-i] > data[name][-(i+1)]:
                return False
        return True

    # 判断最低值指标是否连涨
    def getFrontLowB(self, data, end):
        for i in range(0, end):
            if  data.low[-(i + 1)] > data.low[-i] :
                return False
        return True

    # 判断最低值指标是否连涨
    def getFrontHighB(self, data, end):
        for i in range(0, end):
            if data.high[-(i + 1)] > data.high[-i]  :
                    return False
        return True


    def getFrontLowB2(self, data, end):
        for i in range(0, end):
            if data.low[-i] > data.low[-(i + 1)]  :
                return False
        return True


    # 判断最低值指标是否连涨
    def getFrontHighB2(self, data, end):
        for i in range(0, end):
            if data.high[-i] > data.high[-(i + 1)] :
                return False
        return True